const std = @import("std");
const builtin = @import("builtin");
const Build = std.Build;
const Step = Build.Step;
const mem = std.mem;

// runner.
pub fn build(b: *std.Build) void {
    addExecutables(
        b,
        &[_]std.Target.Os.Tag{.linux},
        std.meta.tags(std.builtin.OptimizeMode), // 4
        // &.{.Debug},
        &[_]std.Target.Cpu.Arch{ .x86_64, .aarch64 },
        b.path("./src/main.zig"),
        "1.1.7",
    );
}

fn addExecutables(
    b: *Build,
    os_tag_s: []const std.Target.Os.Tag,
    optimize_s: []const std.builtin.OptimizeMode,
    arch_s: []const std.Target.Cpu.Arch,
    root_source_file: Build.LazyPath,
    version: []const u8,
) void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){}; // <><>
    defer std.debug.assert(.ok == gpa.deinit());
    const allocator: mem.Allocator = gpa.allocator();

    const app_name = "mnemonic";

    for (os_tag_s) |os_tag| {
        for (optimize_s) |optimize| {
            for (arch_s) |arch| {
                const name: []const u8 = std.fmt.allocPrint(
                    allocator,
                    "{s}_{s}_{s}_{s}_{s}",
                    .{ app_name, @tagName(os_tag), @tagName(arch), @tagName(optimize), version },
                ) catch @panic("nb"); // <><>
                defer allocator.free(name);
                const exe: *Build.Step.Compile = b.addExecutable(.{
                    .name = name,
                    .optimize = optimize,
                    .root_source_file = root_source_file,
                    .target = b.resolveTargetQuery(.{ .os_tag = os_tag, .cpu_arch = arch }),
                });
                c_api.addCSourceFile(exe, b);
                b.installArtifact(exe);
            }
        }
    }
    return;
}

const c_api: type = struct {
    pub fn addCSourceFile(obj: *Step.Compile, b: *std.Build) void {
        obj.linkLibC();
        addSqlite(obj, b);
    }
    fn addSqlite(obj: *Step.Compile, b: *std.Build) void {
        obj.addCSourceFile(.{ .file = b.path("src/sqlite3/sqlite3.c") });
        obj.addIncludePath(b.path("src/sqlite3"));
    }
};
